package com.spark.gaea.utils.json;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.DateDeserializers;
import com.spark.gaea.utils.DateUtil;
import com.spark.gaea.utils.exception.GaeaRuntimeException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.TimeZone;

public final class DateDeserializer extends DateDeserializers.DateDeserializer {
	private static final Logger LOG;

	public DateDeserializer() {
	}

	public DateDeserializer(final DateDeserializer base, final DateFormat df, final String formatString) {
		super(base, df, formatString);
	}

	@Override
	protected DateDeserializer withDateFormat(final DateFormat df, final String formatString) {
		return new DateDeserializer(this, df, formatString);
	}

	@Override
	public Date deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException {
		if (StringUtils.isEmpty(jp.getText())) {
			return this.getEmptyValue();
		}
		if (jp.getCurrentToken() == JsonToken.VALUE_STRING) {
			final String str = jp.getText().trim();
			if (str.length() == 0) {
				return this.getEmptyValue();
			}
			if (this._customFormat != null) {
				this._customFormat.setTimeZone(TimeZone.getTimeZone("GMT+8"));
				synchronized (this._customFormat) {
					try {
						return this._customFormat.parse(str);
					} catch (ParseException e) {
						throw new IllegalArgumentException(
								"Failed to parse Date value '" + str + "' (format: \"" + this._formatString + "\"): "
										+ e.getMessage());
					}
				}
			}
		}
		return this._parseDate(jp, ctxt);
	}

	@Override
	protected Date _parseDate(final JsonParser jp, final DeserializationContext ctxt) throws IOException {
		final String date = jp.getText().trim();
		try {
			return DateUtil.parse(date);
		} catch (GaeaRuntimeException e) {
			DateDeserializer.LOG.warn("反序列化日期时出现了错误：" + date);
			throw new IOException(date, e);
		}
	}

	static {
		LOG = LoggerFactory.getLogger(DateDeserializer.class);
	}
}
